package com.tql.pandian.controller;

import com.ruoyi.common.core.constant.CommonUtil;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.CalculatedValueUtil;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.web.controller.BaseController;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.system.api.RemoteKingdeeService;
import com.tql.pandian.entity.*;
import com.tql.pandian.entity.dto.MainDto;
import com.tql.pandian.entity.dto.SimpleDto;
import com.tql.pandian.mapper.TqlStapProlossMapper;
import com.tql.pandian.service.ICommonService;
import com.tql.pandian.service.IGenCostAnalysService;
import com.tql.pandian.service.ITqlHllShopBillFoodService;
import com.tql.pandian.service.impl.CommonService;
import com.tql.pandian.util.BusinessUtil;
import com.tql.pandian.util.TimeUtil;
import com.tql.pandian.vo.TqlPandianPeriodVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.text.ParseException;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@RestController
@RequestMapping("/genCostAnalys")
@Api(tags = "损益分析")
public class GenCostAnalysController extends BaseController {
    @Autowired
    private IGenCostAnalysService genCostAnalysService;

    @Autowired
    private ICommonService commonService;

    @Autowired
    private TqlStapProlossMapper tqlStapProlossMapper;

    @Autowired
    private RemoteKingdeeService remoteKingdeeService;

    @Autowired
    private RedisService redisService;


    @Autowired
    private ITqlHllShopBillFoodService tqlHllShopBillFoodService;
    private final static String pandianKey = "pandian_gen_key";
    @GetMapping("/gen")
    @ApiOperation("产生物料消耗数据")
    public void gen(@RequestParam("pandianCode") String pandianCode) {
        //  genCostAnalysService.genMaterialSaleChange(pandianPeriodCode);
        try {
//            genCostAnalysService.gen(pandianCode);

            redisService.deleteObject(pandianKey);
            List<Boolean> dataList = new ArrayList<>();
            TqlPandianPeriodVO period = commonService.findEnableGenPharse(pandianCode);
            if (null == period) {
                throw new ServiceException("数据异常，未查到本期数据！");
            }
            //当前时间小于盘点
            try {
              //  int result=this.enrichData(period.getPcode());

                dataList.add(0, true);
                List<TqlHllShopBillFoodPeriod> periodData;
                try {
              // periodData = genCostAnalysService.insertBillFoodPeriodFromBillFoodReport(pandianCode, period);
                    dataList.add(1, true);
                    List<TqlStapProloss> prolossData;
                    try {
//                        prolossData = genCostAnalysService.insertProloss(pandianCode, period);

                        insertProloss1(pandianCode,period);
                        dataList.add(2, true);
                        try {
             //   genCostAnalysService.insertBomcardAnalys(pandianCode,periodData,prolossData);
                            dataList.add(3, true);
                        }catch (Exception e) {
                            dataList.add(3, false);
                            e.printStackTrace();
                        }
                    }catch (Exception e) {
                        dataList.add(2, false);
                        e.printStackTrace();
                    }
                }catch (Exception e) {
                    dataList.add(1, false);
                    e.printStackTrace();
                }
            }catch (Exception e) {
                dataList.add(0, false);
                e.printStackTrace();
            }
            redisService.setCacheList(pandianKey, dataList);


        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    private void insertProloss1(String pandianCode, TqlPandianPeriodVO period) {
  try {
      System.out.println("----------------------------insertProloss1-------------");
      /**
       * 1.获取物料部门关系数据
       */
      String fnumber = StringUtils.getPandianCodeInfo(pandianCode, 1);
      String yyyymmdd = StringUtils.getPandianCodeInfo(pandianCode, 2);
      String monthStr = yyyymmdd.substring(4);
      int month = 0;
      try {
          month = TimeUtil.getMonth(yyyymmdd, "yyyyMMdd");
      } catch (ParseException e) {
          throw new RuntimeException(e);
      }

      // int month = Integer.parseInt(monthStr);
      List<SimpleDto> stapCodeArr1 = commonService.findStapAndDeptFromInAndOut(month, fnumber);
      List<SimpleDto> stapCodeArr2 = commonService.findStapAndDeptFromPandianData(pandianCode);
      List<SimpleDto> union = Stream.concat(stapCodeArr1.stream(), stapCodeArr2.stream())
              .distinct().collect(Collectors.toList());
      List<String> list = union.stream().map(SimpleDto::getDeptStapStr).collect(Collectors.toList());

      /**
       * 2.获取in的详情
       * transferOutNum
       * transferOutAmount
       * transferOutIds
       * 1采购入库单incase 2,门店采购单purcharse 3.分布式调入单 4分布式调出单
       */
      List<SimpleDto> listIncase = commonService.findInDetailByStapAndDeptForIncase(month, list);
      List<SimpleDto> listPrucharse = commonService.findInDetailByStapAndDeptForPurcharse(month, list);
      List<SimpleDto> listTransferIn = commonService.findInDetailByStapAndDeptForTransferIn(month, list);
      List<SimpleDto> listTransferout = commonService.findInDetailByStapAndDeptForTransferout(month, list);


      for (SimpleDto unionE : union) {
          String ds = unionE.getDeptStapStr();
          if (!CollectionUtils.isEmpty(listIncase)) {

              for (SimpleDto incase : listIncase) {
                  if (ds.equals(incase.getDeptStapStr())) {
                      unionE.setIncaseAmount(incase.getIncaseAmount());
                      unionE.setIncaseIds(incase.getIncaseIds());
                      unionE.setIncaseNum(incase.getIncaseNum());
                      unionE.setIncasePrice(incase.getIncasePrice());
                  }
              }

          }


          if (!CollectionUtils.isEmpty(listPrucharse)) {
              for (SimpleDto purcharse : listPrucharse) {
                  if (ds.equals(purcharse.getDeptStapStr())) {
                      unionE.setPurcharseAmount(purcharse.getPurcharseAmount());
                      unionE.setPurcharseIds(purcharse.getPurcharseIds());
                      unionE.setPurcharseNum(purcharse.getPurcharseNum());
                      unionE.setPurcharsePrice(purcharse.getPurcharsePrice());
                  }
              }
          }


          if (!CollectionUtils.isEmpty(listTransferIn)) {
              for (SimpleDto transferIn : listTransferIn) {
                  if (ds.equals(transferIn.getDeptStapStr())) {
                      unionE.setTransferInAmount(transferIn.getTransferInAmount());
                      unionE.setTransferInIds(transferIn.getTransferInIds());
                      unionE.setTransferInNum(transferIn.getTransferInNum());
                      unionE.setTransferPrice(transferIn.getTransferPrice());
                  }
              }
          }


          if (!CollectionUtils.isEmpty(listTransferout)) {
              for (SimpleDto transferOut : listTransferout) {
                  if (ds.equals(transferOut.getDeptStapStr())) {
                      unionE.setTransferOutAmount(transferOut.getTransferInAmount());
                      unionE.setTransferOutIds(transferOut.getTransferInIds());
                      unionE.setTransferOutNum(transferOut.getTransferInNum());
                      unionE.setPrice(transferOut.getTaxPrice());
                  }
              }
          }


      }


      /**
       *3.获取out的详情
       */
      Long std = Long.parseLong(TimeUtil.getStringDate(period.getStarttime()));
      Long etd = Long.parseLong(TimeUtil.getStringDate(period.getEndtime()));
      List<SimpleDto> outs = commonService.findOutDetailByDeptStap(month, list, std, etd);

      if (!CollectionUtils.isEmpty(outs)) {
          for (SimpleDto unionE : union) {
              String ds = unionE.getDeptStapStr();
              for (SimpleDto out : outs) {
                  if (ds.equals(out.getDeptStapStr())) {
                      unionE.setOutStapAmount(out.getOutStapAmount());
                      unionE.setOutStapNum(out.getOutStapNum());
                  }
              }
          }
      }
      /**
       *4.获取上次盘点的详情
       */
      List<SimpleDto> lastPandianList = commonService.findLastPandianDetail(pandianCode, list);
      if (!CollectionUtils.isEmpty(lastPandianList)) {
          for (SimpleDto unionE : union) {
              String ds = unionE.getDeptStapStr();
              for (SimpleDto lastPandian : lastPandianList) {
                  if (ds.equals(lastPandian.getDeptStapStr())) {
                      unionE.setLastPandianAmount(lastPandian.getThisPandianAmount());
                      unionE.setLastPandianCode(lastPandian.getPandianCode());
                      unionE.setLastPandianId(lastPandian.getThisPandianId());
                      unionE.setLastPandianNum(lastPandian.getThisPandianNum());
                  }

              }
          }
      }

      /**
       *5.获取当前盘点的详情
       */

      List<SimpleDto> thisPandianList = commonService.findThisPandianDetail(pandianCode, list);
      if (!CollectionUtils.isEmpty(thisPandianList)) {
          for (SimpleDto unionE : union) {
              String ds = unionE.getDeptStapStr();
              for (SimpleDto thisPandian : thisPandianList) {
                  if (ds.equals(thisPandian.getDeptStapStr())) {

                      //   unionE.setThisPandianAmount(thisPandian.getThisPandianAmount());
                      unionE.setThisPandianId(thisPandian.getThisPandianId());
                      unionE.setThisPandianNum(thisPandian.getThisPandianNum());
                      unionE.setThisPandianPrice(thisPandian.getThisPandianPrice());
                  }

              }
          }
      }
      List<MainDto> mains = null;
      if (!CollectionUtils.isEmpty(union)) {
          mains = new ArrayList<>();
          for (SimpleDto unionE : union) {
              String uuid = UUID.randomUUID().toString();
              unionE.setUuid(uuid);
              unionE.setMonth(month+"");
              unionE.setPandianCode(pandianCode);
              BigDecimal inAmout = BusinessUtil.getInAmout(unionE);
              BigDecimal inAmout1 = BusinessUtil.getRealCostAmount(unionE.getLastPandianAmount(),unionE.getLastPandianPrice(),inAmout,unionE.getThisPandianAmount(),unionE.getThisPandianPrice());
              BigDecimal InNum = BusinessUtil.getInNum(unionE);
              BigDecimal inNum1=BusinessUtil.getRealCost(unionE.getLastPandianAmount(),InNum,unionE.getThisPandianAmount());
              BigDecimal outAmout = null == unionE.getOutStapAmount() ? BigDecimal.ZERO : unionE.getOutStapAmount();
              BigDecimal outNum = null == unionE.getOutStapNum() ? BigDecimal.ZERO : unionE.getOutStapNum();
              BigDecimal prolossNum = BusinessUtil.getProlossNum(inNum1,outNum);
              BigDecimal prolossAmout = BusinessUtil.getProlossAmout(inAmout1, outAmout);
              MainDto main = new MainDto();
              main.setUuid(uuid);
              main.setPandianCode(pandianCode);
              main.setInAmout(inAmout1);//实际成本
              main.setInNum(inNum1);
              main.setOutAmout(outAmout);
              main.setOutNum(outNum);//理论成本
              //实际成本小于理论成本  返回1 成本卡偏大
              //实际成本大于理论成本  返回2 成本卡偏小
              main.setCompareType(BusinessUtil.getBomParse(inNum1,outNum));
              main.setStapCode(unionE.getStapCode());
              main.setDeptCode(unionE.getDeptCode());
              main.setShopCode(fnumber);
              main.setProlossNum(prolossNum);
              main.setProlossAmout(prolossAmout);
              mains.add(main);
          }
      }

//      MainDto dto=mains.get(0);
//      List<MainDto> newm=new ArrayList<>();
//      newm.add(dto);
      commonService.batch(mains, union);

  }catch (Exception ex)
  {
      ex.printStackTrace();
      logger.info("-----insertProloss1-------"+ex.getMessage());
  }


    }




    @GetMapping("/regen")
    @ApiOperation("重新计算")
    public void regen(@RequestParam("pandianCode") String pandianCode) {
        String fnumber = StringUtils.getPandianCodeInfo(pandianCode, 1);
        String yyyymmdd = StringUtils.getPandianCodeInfo(pandianCode, 2);
        String monthStr = yyyymmdd.substring(4);
        int month = 0;
        try {
            month = TimeUtil.getMonth(yyyymmdd, "yyyyMMdd");
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        TqlPandianPeriodVO period = commonService.findEnableGenPharse(pandianCode);
        Long std = Long.parseLong(TimeUtil.getStringDate(period.getStarttime()));
        Long etd = Long.parseLong(TimeUtil.getStringDate(period.getEndtime()));
        //1.bill_food->bill_food_reportday
        String shopID=commonService.getEnabledHllShopIdByKingdeeFnumber(fnumber);
        commonService.batchBillFoodReport(month,shopID);
        //2.生成outchange,先删后插入
        //做过bom的food
        List<String> enableFoodCodes=tqlHllShopBillFoodService.findEnableFoodCode(shopID);
        //billFoodReport的数据
        List<TqlStapOutChange> entityList= tqlHllShopBillFoodService.getBillFoodReportList1(month,shopID,std,etd);
        //利用已经做过的bom集合enableFoodCodes过滤
        List<TqlStapOutChange> reportDayBillFoods = entityList.stream()
                .filter(entity -> enableFoodCodes.contains(entity.getFoodCode()))
                .collect(Collectors.toList());
        List<TqlStapOutChange> newEntityList = new ArrayList<>();
        if (!reportDayBillFoods.isEmpty()) {
            for (TqlStapOutChange outChange : reportDayBillFoods) {
                List<TqlStapOutChangeBomInfo> bomInfoList = tqlHllShopBillFoodService.selectShopBillFoodReportDayBomInfo(outChange.getShopId(), outChange.getFoodCode());
                if (bomInfoList.isEmpty()) {
                    continue;
                }
                for (TqlStapOutChangeBomInfo bomInfo : bomInfoList) {
                    TqlStapOutChange dto=BusinessUtil.getOutDetail(bomInfo,outChange);
                    newEntityList.add(dto);
                }
            }
            //清一下out表 某个店某个时间段
            tqlHllShopBillFoodService.clearOutByShopIdAndReportDate(month,shopID,std,etd);

            String shopBillFoodReportdayTableName=CommonUtil.TableName_ShopBillFoodDetail+month;
            tqlHllShopBillFoodService.insertAndUpdate1(month,shopBillFoodReportdayTableName,newEntityList);
            //3.proloss
            insertProloss1(pandianCode,period);

        }






        //3.生成proloss,先删后插入








    }


    @GetMapping("/getGenStatus")
    @ApiOperation("获取产生物料状态")
    public AjaxResult getGenStatus() {
       List<Boolean> status =  genCostAnalysService.getGenStatus();
       return success(status);
    }



    public int enrichData(String pcode) {
        String localDate = TimeUtil.longDatetoDate(pcode);
        String yyyymmdd = TimeUtil.getCurrentDate();
        logger.info("执行补偿动作开始localDate:{}---yyyymmdd:{}",localDate,yyyymmdd);
        //只获取已经关联的门店
        List<String> relDeptIds = tqlHllShopBillFoodService.selectRelDeptIds();
        if (Long.parseLong(pcode) < Long.parseLong(yyyymmdd)) {
            localDate = LocalDate.now().toString();
//            remoteKingdeeService.saveMaterialIncase(localDate);
//            remoteKingdeeService.saveMaterialTransferin(localDate);
//            remoteKingdeeService.saveMaterialTransferout(localDate);
//            tqlHllShopBillFoodService.insertBillFoodReportDay();
//            tqlHllShopBillFoodService.insertStapOutChange(0);

            String finalLocalDate = localDate;
            CompletableFuture<Void> task1 = CompletableFuture.runAsync(() -> remoteKingdeeService.saveMaterialIncase(finalLocalDate));
            String finalLocalDate1 = localDate;
            CompletableFuture<Void> task2 = CompletableFuture.runAsync(() -> remoteKingdeeService.saveMaterialTransferin(finalLocalDate1));
            String finalLocalDate2 = localDate;
            CompletableFuture<Void> task3 = CompletableFuture.runAsync(() -> remoteKingdeeService.saveMaterialTransferout(finalLocalDate2));
            CompletableFuture<Void> task4 = CompletableFuture.runAsync(() -> tqlHllShopBillFoodService.insertBillFoodReportDay());
            CompletableFuture<Void> task5 = CompletableFuture.runAsync(() -> tqlHllShopBillFoodService.insertStapOutChange1(0,relDeptIds));


            CompletableFuture<Void> allTasks = CompletableFuture.allOf(task1, task2, task3, task4, task5);
            allTasks.join(); // 等待所有任务完成
            logger.info("执行补偿动作结束localDate:{}---yyyymmdd:{}",localDate,yyyymmdd);
            return 1;

        }
        else {
            return 2;
        }
    }




    @GetMapping("/test")
    @ApiOperation("")
    public void test(@RequestParam("pandianCode") String pandianCode) throws ParseException {
        TqlPandianPeriodVO period = commonService.findEnableGenPharse(pandianCode);
        List<TqlHllShopBillFoodPeriod> periodData = genCostAnalysService.insertBillFoodPeriodFromBillFoodReport(pandianCode, period);
        List<TqlHllShopBillFoodPeriod> periodData1 = genCostAnalysService.selectBillFoodPeriod(pandianCode);


    }


    @GetMapping("/bomCardParse")
    public AjaxResult bomCardParse(@RequestParam("pandianCode") String pandianCode, @RequestParam("type")String type) throws ParseException {

        String key="BCP"+pandianCode;
        String value=(String) redisService.getCacheObject(key);
        if(Objects.isNull(value))
        {
            TqlPandianPeriodVO period = commonService.findEnableGenPharse(pandianCode);
            List<TqlHllShopBillFoodPeriod> periodData = genCostAnalysService.insertBillFoodPeriodFromBillFoodReport(pandianCode, period);
            // List<TqlHllShopBillFoodPeriod> periodData1 = genCostAnalysService.selectBillFoodPeriod(pandianCode);
            List<TqlStapProloss> prolossData=genCostAnalysService.selectProloss(pandianCode);
            if(Objects.isNull(value))//说明没有进项BOM判断
            {
                genCostAnalysService.insertBomcardAnalys(pandianCode,periodData,prolossData);
            }
            redisService.setCacheObject(key,"BCP");
        }




        if(null==type) return success();
        List<FoodAndBom> list=null;
        //TYPE 成本卡偏大1 对应数据库（type =1 或者 type >2） 且 type!=-1
        if("1".equals(type))
        {
            list= commonService.findBomCardParse(pandianCode,type);
        }
        else if("2".equals(type))
        {
            list= commonService.findBomCardParse(pandianCode,type);
        }
        return success(list);
    }







}

